{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Plotting traces (collections)\n",
    "This Tutorial explains how to customize network plots in pandapower using plotly. Each pandapower network element can be translated into a plotly trace with all corresponding properties..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandapower as pp\n",
    "import pandapower.networks as nw\n",
    "import pandapower.plotting.plotly as pplotly\n",
    "from pandas import Series"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want to have full control over the layout of your plot, you can individually create and plot collections with the pandapower plotting module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "net = nw.mv_oberrhein()\n",
    "\n",
    "lc = pplotly.create_line_trace(net,net.line.index, color='black')\n",
    "bc = pplotly.create_bus_trace(net, net.bus.index, size=10, color=\"orange\",\n",
    "                              infofunc=Series(index=net.bus.index,\n",
    "                                              data=net.bus.name + '<br>' + net.bus.vn_kv.astype(str) + ' kV'))\n",
    "\n",
    "pplotly.draw_traces(bc + lc, figsize=1, aspectratio=(8,6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Order of ploting traces is as ordered in the `draw_traces` function. So, in order to plot buses in front of lines first lines and then buses need to be set in the input traces list:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pplotly.draw_traces(lc + bc , figsize=1, aspectratio=(8,6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Highligting\n",
    "Specific lines or buses can be highlighted by creating extra line collections in different colors.\n",
    "\n",
    "In this example, we plot lines that are longer than 2 km green and buses with a voltage below 0.98 pu red.\n",
    "\n",
    "First, we create a line collection for all lines in grey and a line collection for only the long lines in green:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "long_lines = net.line[net.line.length_km > 2.].index\n",
    "lc = pplotly.create_line_trace(net, net.line.index, color=\"grey\")\n",
    "lcl = pplotly.create_line_trace(net, long_lines, color=\"green\", width=2,\n",
    "                                infofunc=Series(index=net.line.index, \n",
    "                                                data=net.line.name[long_lines] + '<br>' + net.line.length_km[long_lines].astype(str) + ' km'))\n",
    "\n",
    "low_voltage_buses = net.res_bus[net.res_bus.vm_pu < 0.98].index\n",
    "bc = pplotly.create_bus_trace(net, net.bus.index, size=10, color=\"blue\")\n",
    "bch = pplotly.create_bus_trace(net, low_voltage_buses, size=10, color=\"red\")\n",
    "\n",
    "pplotly.draw_traces(bc + bch + lc + lcl )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## Highlighting with the Topology Package\n",
    "Colors palette for plotly can be obtained using function `plotting.plotly.get_plotly_color_palette(n)` where argument `n` defines number of colors that will be returned in a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pandapower.plotting.plotly import get_plotly_color_palette\n",
    "\n",
    "net = nw.mv_oberrhein()\n",
    "\n",
    "mg = pp.topology.create_nxgraph(net, nogobuses=set(net.trafo.lv_bus.values) | set(net.trafo.hv_bus.values))\n",
    "collections = []\n",
    "ai = 0\n",
    "islands = list(pp.topology.connected_components(mg)) # getting connected components of a graph\n",
    "colors = get_plotly_color_palette(len(islands)) # getting a color for each connected component\n",
    "for color, area in zip(colors, islands):\n",
    "    collections += pplotly.create_bus_trace(net, area, size=5, color=color, trace_name='feeder {0}'.format(ai))\n",
    "    ai += 1\n",
    "collections += pplotly.create_line_trace(net, net.line.index, color=\"grey\")\n",
    "collections += pplotly.create_bus_trace(net, net.ext_grid.bus.values, patch_type=\"square\", size=10,\n",
    "                                        color=\"yellow\")\n",
    "pplotly.draw_traces(collections)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Collection on mapbox\n",
    "If network geo-data are not in lat/long form, there is a function `geo_data_to_latlong` which can be used to transform entire network geodata from a specific projection to lat/long:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "net = nw.mv_oberrhein()\n",
    "pplotly.geo_data_to_latlong(net, projection='epsg:31467') #transforming geodata to lat/long\n",
    "\n",
    "lc = pplotly.create_line_trace(net, net.line.index, color='purple')\n",
    "bc = pplotly.create_bus_trace(net, net.bus.index,size=10,color=\"orange\",\n",
    "                              infofunc=Series(index=net.bus.index,\n",
    "                                              data=net.bus.name + '<br>' + net.bus.vn_kv.astype(str) + ' kV'))\n",
    "pplotly.draw_traces(lc + bc, on_map=True, map_style='dark')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Colormaps\n",
    "Colormaps plots are available for plotly by setting `cmap=True` in create functions. By default line loading and bus voltage magnitudes will be used for coloring."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "net = nw.mv_oberrhein()\n",
    "bt = pplotly.create_bus_trace(net, cmap=True)\n",
    "lt = pplotly.create_line_trace(net, cmap=True)\n",
    "pplotly.draw_traces(lt + bt, showlegend=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Some customization is possible in regard to: limits, choosing a colormap, colorbar title, etc."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lt = pplotly.create_line_trace(net, cmap='Blues', cmin=0, cmax=100, cbar_title = 'Line loading [%]')\n",
    "pplotly.draw_traces(lt, showlegend=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively, any other values can be used for colormaps, with also some customization in regard to limits, choosing a colormap, colorbar title, etc. An axample with coloring according to line length:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lt = pplotly.create_line_trace(net, cmap_vals=net.line.length_km, cmap=True, cbar_title = 'Line length [km]')\n",
    "pplotly.draw_traces(lt, showlegend=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Customized hover-info\n",
    "Information that pop-ups when a bus or a line is pointed with mouse-cursor is called hover-info. By default it is set to bus/line name, but it can be customized by setting a list of strings to `infofunc` argument. A newline is defined using `<br>`. See a representative example hereafter (try getting hoverinfo by pointing a cursor above each bus):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bc = pplotly.create_bus_trace(net, [1,2,3,4,5], size=15,\n",
    "                              infofunc=Series(index=net.bus.index, data=net.bus.name + '<br>' + \n",
    "                                              net.bus.vn_kv.astype(str) + ' kV' + '<br>' +\n",
    "                                              'this is one of the 5 buses...'))\n",
    "pplotly.draw_traces(bc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "More tutorials about interactive plots using ploltly:\n",
    "* [built-in interactive plots](http://nbviewer.jupyter.org/github/e2nIEE/pandapower/blob/develop/tutorials/plotly_built-in.ipynb)\n",
    "* [interactive plots on maps](http://nbviewer.jupyter.org/github/e2nIEE/pandapower/blob/develop/tutorials/plotly_maps.ipynb)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
